package com.wsg.dep.seq;


import com.wsg.dep.core.WaitStrategy;
import com.wsg.dep.exception.InsufficientCapacityException;
import com.wsg.dep.util.Utils;

/**
 * 单例生成序列跟踪管理器
 */
public class SingleProducerSequencer extends SingleProducerSequencerFields{
    /**
     * 避免伪共享（False Sharing）问题
     */
    protected long p1, p2, p3, p4, p5, p6, p7;

    /**
     * 构造函数
     * @param bufferSize 缓存大小
     * @param waitStrategy 等待策略
     */
    public SingleProducerSequencer(int bufferSize, WaitStrategy waitStrategy)
    {
        super(bufferSize, waitStrategy);
    }

    @Override
    public boolean hasAvailableCapacity(int requiredCapacity) {
        return hasAvailableCapacity(requiredCapacity, false);
    }


    private boolean hasAvailableCapacity(int requiredCapacity, boolean doStore)
    {
        long nextValue = this.nextValue;

        long wrapPoint = (nextValue + requiredCapacity) - bufferSize;
        long cachedGatingSequence = this.cachedValue;

        if (wrapPoint > cachedGatingSequence || cachedGatingSequence > nextValue)
        {
            if (doStore)
            {
                cursor.setVolatile(nextValue);  // StoreLoad fence
            }

            long minSequence = Utils.getMinimumSequence(gatingSequences, nextValue);
            this.cachedValue = minSequence;

            if (wrapPoint > minSequence)
            {
                return false;
            }
        }

        return true;
    }

    @Override
    public long remainingCapacity() {
        return 0;
    }

    @Override
    public long next() {
        return 0;
    }

    @Override
    public long next(int sequence) {
        return 0;
    }

    @Override
    public long tryNext() throws InsufficientCapacityException {
        return 0;
    }

    @Override
    public long tryNext(int sequence) throws InsufficientCapacityException {
        return 0;
    }

    @Override
    public void publish(long sequence) {

    }

    @Override
    public void publish(long lower, long upper) {

    }

    @Override
    public void claim(long sequence) {

    }

    @Override
    public boolean isAvailable(long sequence) {
        return false;
    }

    @Override
    public long getHighestPublishedSequence(long nextSequence, long availableSequence) {
        return 0;
    }
}
